#include <iostream>
#include <fstream>
#include <cstring>
#include "my_strblob.h"

using namespace std;

void test_strblob()
{
    StrBlob b1;
    {
        StrBlob b2 = {"a", "an", "the"};
        b1 = b2;
        b2.push_back("about");
        cout << b2.size() << endl;
    }
    cout << b1.size() << endl;
    cout << b1.front() << " " << b1.back() << endl;

    const StrBlob b3 = b1;
    cout << b3.front() << " " << b3.back() << endl;
}

vector<int>* new_vector(void)
{
    return new (nothrow) vector<int>;
}

void read_int(vector<int>* pv)
{
    int v;
    while (cin >> v) {
        pv->push_back(v);
    }
}

void print_int(vector<int>* pv)
{
    for (const auto &v : *pv) {
        cout << v << " ";
    }
    cout << endl;
}

void pr_12_6()
{
    vector<int> *pv = new_vector();
    if (!pv) {
        cout << "内存不足！" << endl;
    }
    read_int(pv);
    print_int(pv);
    delete pv;     // 删除动态分配的内存
    pv = nullptr;  // 设置动态分配的指针为 nullptr
}

shared_ptr<vector<int>> new_vector_shared(void)
{
    return make_shared<vector<int>>();
}

void read_int(shared_ptr<vector<int>> spv)
{
    int v;
    while (cin >> v) {
        spv->push_back(v);
    }
}

void print_int(shared_ptr<vector<int>> spv)
{
    for (const auto &v : *spv) {
        cout << v << " ";
    }
    cout << endl;
}

void pr_12_7()
{
    auto spv = new_vector_shared();
    read_int(spv);
    print_int(spv);
}

void pr_12_8()
{
    int *q = new int(42), *r = new int(100);
    r = q;  // r 指向的动态内存现在没有指针进行管理
    auto q2= make_shared<int>(42), r2 = make_shared<int>(100);
    r2 = q2;  // 自动管理内存释放
}

struct destination {};
struct connection {};

connection connect(destination *pd)
{
    cout << "打开连接" << endl;
    return connection();
}

void disconnection(connection c)
{
    cout << "关闭连接" << endl;
}

// 未使用 shared_ptr 的版本
void f(destination &d)
{
    cout << "直接管理 connect" << endl;
    connection c = connect(&d);
    // 忘记调用 disconnection 关闭连接
    cout << endl;
}

// 删除器
void end_connection(connection *p) { disconnection(*p); }

// 使用 shared_ptr 的版本
void f1(destination &d)
{
    cout << "用 shared_ptr 管理 connect" << endl;
    connection c = connect(&d);
    shared_ptr<connection> p(&c, end_connection);
    // 忘记调用 disconnection 关闭连接
    cout << endl;
}

void pr_12_14()
{
    destination d;
    f(d);
    f1(d);
}

// 使用 lambda 表达式
void f2(destination &d)
{
    cout << "用 shared_ptr 和 lambda 管理 connect" << endl;
    connection c = connect(&d);
    shared_ptr<connection>p(&c,
                            [](connection *p) { disconnection(*p); });
}

void pr_12_19()
{
    StrBlob b1;
    {
        StrBlob b2 = {"a", "an", "the"};
        b1 = b2;
        b2.push_back("about");
        cout << b2.size() << endl;
    }
    cout << b1.size() << endl;
    cout << b1.front() << " " << b1.back() << endl;

    const StrBlob b3 = b1;
    cout << b3.front() << " " << b3.back() << endl;

    for (auto it = b1.begin(); neq(it, b1.end()); it.incr()) {
        cout << it.deref() << endl;
    }
}

void pr_12_20()
{
    ifstream in("file");
    if (!in) {
        cerr << "无法打开输入文件!" << endl;
        return;
    }
    StrBlob b;
    string s;
    while (getline(cin, s)) {
        b.push_back(s);
    }
    for (auto it = b.begin(); neq(it, b.end()); it.incr()) {
        cout << it.deref() << " ";
    }
    cout << endl;
}

void pr_12_22()
{
    const StrBlob b = {"Hello", "World", "!"};
    for (auto it = b.begin(); neq(it, b.end()); it.incr()) {
        cout << it.deref() << " ";
    }
    cout << endl;
}

void pr_12_23()
{
    const char *c1 = "Hello";
    const char *c2 = "World";
    // 字符串所需空间等于字符数 +1
    char *r = new char[strlen(c1) + strlen(c2) + 1];
    strcpy(r, c1);  // 拷贝第一个字符串常量
    strcat(r, c2);  // 连接第二个字符串常量
    cout << r << endl;

    string s1 = "Hello";
    string s2 = "World";
    strcpy(r, (s1 + s2).c_str());  // 拷贝连接结果
    cout << r << endl;

    delete [] r;  // 释放动态数组
}

int pr_12_24()
{
    char c;
    // 分配 20 个字符的动态数组，最多存放 19 个字符
    char *r = new char[20];
    int l = 0;
    while (cin.get(c)) {
        if (isspace(c)) {  // 空格符、制表符等空白符
            break;
        }
        r[l++] = c;  // 存入动态数组
        if (l == 20) {  // 已读入 19 个字符
            cout << "达到数组容量的上限" << endl;
            break;
        }
    }
    r[l] = 0;
    cout << r << endl;
    // 释放动态数组
    delete [] r;
    return 0;
}

int pr_12_25()
{
    allocator<string> alloc;  //
    // 分配 100 个未初始化的 string
    auto const p = alloc.allocate(100);
    string s;
    string *q = p;  // q 指向第一个 string
    while (cin >> s && q != p + 100) {
        alloc.construct(q++, s);  // 用 s 初始化 *q
    }
    const size_t size = q - p;  // 记住读取了多少个 string
    // 使用数组
    for (size_t i = 0; i != size; i++) {
        cout << p[i] << " " << endl;
    }
    // 使用完毕后需要释放已构造的 string
    while (q != p) {
        alloc.destroy(--q);
    }
    alloc.deallocate(p, 100);  // 释放内存
    return 0;
}

int main()
{

    return 0;
}
